package cn.com.acca.ma.service.impl;

import cn.com.acca.ma.common.util.DateUtil;
import cn.com.acca.ma.common.util.PropertiesUtil;
import cn.com.acca.ma.constant.RobotName;
import cn.com.acca.ma.model.HistoryRobotAccountLog;
import cn.com.acca.ma.model.ModelMACDGoldCross;
import cn.com.acca.ma.pojo.SuccessRateOrPercentagePojo;
import cn.com.acca.ma.service.ModelMACDGoldCrossService;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.XYTextAnnotation;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.DefaultXYDataset;
import org.jfree.ui.RectangleInsets;

import java.awt.*;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class ModelMACDGoldCrossServiceImpl extends BaseServiceImpl<ModelMACDGoldCrossServiceImpl, ModelMACDGoldCross> implements ModelMACDGoldCrossService {

    /*********************************************************************************************************************
     *
     * 												按日期计算数据
     *
     *********************************************************************************************************************/
    /**
     * 使用日线级别MACD金叉模型算法，根据endDate日期，向表MDL_MACD_GOLD_CROSS插入数据
     *
     * @param multithreading
     */
    public void writeModelMACDGoldCrossIncr(boolean multithreading) {
        String macdGoldCrossEndDate = PropertiesUtil.getValue(MODEL_MACD_GOLD_CROSS_PROPERTIES, "macd.gold.cross.end_date");
        modelMACDGoldCrossDao.writeModelMACDGoldCrossIncr(multithreading, macdGoldCrossEndDate);
    }

    /*********************************************************************************************************************
     *
     * 												   	创建图表
     *
     *********************************************************************************************************************/
    /**
     * 创建MACD金叉散点图
     *
     * @param multithreading
     */
    @SuppressWarnings("rawtypes")
    public void createMACDGoldCrossScatterPlotPicture(boolean multithreading) {
        String beginDate = PropertiesUtil.getValue(MODEL_MACD_GOLD_CROSS_PICTURE_PROPERTIES, "macd.gold.cross.scatter_plot.begin_date");
        String endDate = PropertiesUtil.getValue(MODEL_MACD_GOLD_CROSS_PICTURE_PROPERTIES, "macd.gold.cross.scatter_plot.end_date");

        // 从表MDL_MACD_GOLD_CROSS中获取PROFIT_LOSS大于零的记录
        List<ModelMACDGoldCross> profitMACDGoldCrossList = modelMACDGoldCrossDao.getProfitMACDGoldCross(multithreading);
        // 从表MDL_MACD_GOLD_CROSS中获取PROFIT_LOSS小于零的记录
        List lossMACDGoldCrossList = modelMACDGoldCrossDao.getLossMACDGoldCross(multithreading, beginDate, endDate);
        // 用于存储需要最终显示的数据
        double[][] data = new double[2][];
        data[0] = new double[lossMACDGoldCrossList.size()];
        data[1] = new double[lossMACDGoldCrossList.size()];

        for (int i = 0; i < lossMACDGoldCrossList.size(); i++) {
            Object[] obj = (Object[]) lossMACDGoldCrossList.get(i);
            double dif = Double.parseDouble(obj[0].toString());
            double dea = Double.parseDouble(obj[1].toString());
//			logger.info(dif);
//			logger.info(dea);
            data[0][i] = dif;
            data[1][i] = dea;
        }

        DefaultXYDataset xyDataset = new DefaultXYDataset();
        xyDataset.addSeries("Profit MACD Gold Cross", data);

        JFreeChart chart = ChartFactory.createScatterPlot("MACD GOld Cross Scatter Plot",
                "Profit Percentage", "Average of Dif and Dea", xyDataset, PlotOrientation.VERTICAL, true, false, false);
        XYPlot plot = (XYPlot) chart.getPlot();
        plot.setNoDataMessage("NO DATA");
        plot.setDomainZeroBaselineVisible(true);
        plot.setRangeZeroBaselineVisible(true);

        XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer();
        renderer.setSeriesOutlinePaint(0, Color.black);
        renderer.setUseOutlinePaint(true);

        // x axis
        NumberAxis domainAxis = (NumberAxis) plot.getDomainAxis();
        domainAxis.setAutoRange(true);

        // Y axis
        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setAutoRange(true);

        XYTextAnnotation textAnnotation = new XYTextAnnotation("123", 370, 25); // r value
        textAnnotation.setPaint(Color.BLUE);
        textAnnotation.setToolTipText("Correlation Coefficient");

        plot.addAnnotation(textAnnotation);

        try {
            FileOutputStream fos = new FileOutputStream(PICTURE_PATH + "profit_macd_gold_cross/" + beginDate + "-" + endDate + PICTURE_FORMAT);
            // 将统计图标输出成JPG文件
            ChartUtilities.writeChartAsJPEG(fos, // 输出到哪个输出流
                    1, // JPEG图片的质量，0~1之间
                    chart, // 统计图标对象
                    imageWidth, // 宽
                    IMAGE_HEIGHT, // 高
                    null // ChartRenderingInfo 信息
            );
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * MACD交易方法成功时，dif和dea的分布图。profitLoss为true时表示盈利，为true时表示亏损
     *
     * @param multithreading
     * @param profitLoss
     */
    public void createMACDSuccessDidDeaScatterPlotPicture(boolean multithreading, boolean profitLoss) {
        logger.info("开始创建MACD交易方法成功时，dif和dea的分布图");

        String beginDate = PropertiesUtil.getValue(MODEL_MACD_GOLD_CROSS_PICTURE_PROPERTIES, "macd.gold.cross.success.dif.dea.begin_date");
        String endDate = PropertiesUtil.getValue(MODEL_MACD_GOLD_CROSS_PICTURE_PROPERTIES, "macd.gold.cross.success.dif.dea.end_date");

        // 从表MDL_MACD_GOLD_CROSS中获取PROFIT_LOSS小于零的记录
        List macdGoldCrossSuccessDifDeaList = modelMACDGoldCrossDao.getMACDGoldCrossSuccessDifDea(multithreading, beginDate, endDate, profitLoss);
        // 用于存储需要最终显示的数据
        double[][] data = new double[2][];
        data[0] = new double[macdGoldCrossSuccessDifDeaList.size()];
        data[1] = new double[macdGoldCrossSuccessDifDeaList.size()];

        for (int i = 0; i < macdGoldCrossSuccessDifDeaList.size(); i++) {
            Object[] obj = (Object[]) macdGoldCrossSuccessDifDeaList.get(i);
            double dif = Double.parseDouble(obj[0].toString());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            long date = 0;
            try {
                date = sdf.parse(obj[1].toString()).getTime();
            } catch (ParseException e) {
                e.printStackTrace();
            }
            double dea = Double.parseDouble(String.valueOf(date));
//			logger.info(dif);
//			logger.info(dea);
            data[0][i] = dif;
            data[1][i] = dea;
        }

        DefaultXYDataset xyDataset = new DefaultXYDataset();
        xyDataset.addSeries("MACD Gold Cross Success Dif Dea", data);

        JFreeChart chart = ChartFactory.createScatterPlot("MACD GOld Cross Success Dif Dea Scatter Plot",
                "(Dif + Dea) / 2", "Date", xyDataset, PlotOrientation.VERTICAL, true, false, false);
        XYPlot plot = (XYPlot) chart.getPlot();
        plot.setNoDataMessage("NO DATA");
        plot.setDomainZeroBaselineVisible(true);
        plot.setRangeZeroBaselineVisible(true);

        XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer();
        renderer.setSeriesOutlinePaint(0, Color.black);
        renderer.setUseOutlinePaint(true);

        // x axis
        NumberAxis domainAxis = (NumberAxis) plot.getDomainAxis();
        domainAxis.setAutoRange(true);

        // Y axis
        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setAutoRange(true);

        XYTextAnnotation textAnnotation = new XYTextAnnotation("123", 370, 25); // r value
        textAnnotation.setPaint(Color.BLUE);
        textAnnotation.setToolTipText("Correlation Coefficient");

        plot.addAnnotation(textAnnotation);

        try {
            FileOutputStream fos = new FileOutputStream(PICTURE_PATH + "macd_gold_cross_success_dif_dea/" + beginDate + "-" + endDate + (profitLoss == true ? "_profit" : "_loss") + PICTURE_FORMAT);
            // 将统计图标输出成JPG文件
            ChartUtilities.writeChartAsJPEG(fos, // 输出到哪个输出流
                    1, // JPEG图片的质量，0~1之间
                    chart, // 统计图标对象
                    imageWidth, // 宽
                    IMAGE_HEIGHT, // 高
                    null // ChartRenderingInfo 信息
            );
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建MACD金叉算法成功率图
     *
     * @param multithreading
     */
    @SuppressWarnings({"deprecation", "rawtypes"})
    public void createMACDSuccessRatePicture(boolean multithreading) {
        String beginDate = PropertiesUtil.getValue(MODEL_MACD_GOLD_CROSS_PICTURE_PROPERTIES, "macd.gold.cross.success.rate.begin_date");
        String endDate = PropertiesUtil.getValue(MODEL_MACD_GOLD_CROSS_PICTURE_PROPERTIES, "macd.gold.cross.success.rate.end_date");
        Integer dateNumber = Integer.parseInt(PropertiesUtil.getValue(MODEL_MACD_GOLD_CROSS_PICTURE_PROPERTIES, "macd.gold.cross.success.rate.date_number"));

        TimeSeriesCollection timeSeriesCollection = new TimeSeriesCollection();
        TimeSeries allStockCloseSeries = new TimeSeries("All Stock Close", org.jfree.data.time.Day.class);
        TimeSeries macdSuccessRateSeries = new TimeSeries("MACD Success Rate", org.jfree.data.time.Day.class);

        // 获取某一段时间内平均价格中的最大价格和最小价格
        List maxMinList = stockTransactionDataDao.getMaxMinAverageCloseWeek(multithreading, beginDate, endDate);
        double maxClose = Double.parseDouble(((Object[]) maxMinList.get(0))[0].toString());
        double minClose = Double.parseDouble(((Object[]) maxMinList.get(0))[1].toString());

        List averageAllCloseList = stockTransactionDataDao.getAverageCloseWithDate(multithreading, beginDate, endDate, false, "all");
        List<SuccessRateOrPercentagePojo> macdGoldCrossSuccessRateList = modelMACDGoldCrossDao.getMACDGoldCrossSuccessRate(multithreading, beginDate, endDate, dateNumber);

        for (int i = 0; i < averageAllCloseList.size(); i++) {
            Object[] obj = (Object[]) averageAllCloseList.get(i);
            Date date = (Date) obj[0];
            int year = DateUtil.getYearFromDate(date);
            int month = DateUtil.getMonthFromDate(date);
            int day = DateUtil.getDateFromDate(date);
            Double value = Double.valueOf(obj[1].toString());
            allStockCloseSeries.add(new Day(day, month, year), this.averageCloseAfterAdjust(value, maxClose, minClose));
        }
        timeSeriesCollection.addSeries(allStockCloseSeries);

        for (int i = 0, j = 0; i < averageAllCloseList.size() && j < macdGoldCrossSuccessRateList.size(); ) {
            Date averageAllCloseListDate = DateUtil.stringToDate(((Object[]) averageAllCloseList.get(i))[0].toString().replace("-", ""));
            Date macdSuccessRateListDate = macdGoldCrossSuccessRateList.get(j).getTransactionDate();

            if (averageAllCloseListDate.equals(macdSuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                double value = Double.parseDouble(macdGoldCrossSuccessRateList.get(j).getSuccessRateOrPercentage().toString());
                macdSuccessRateSeries.add(new Day(day, month, year), value);
                i++;
                j++;
            } else if (averageAllCloseListDate.before(macdSuccessRateListDate)) {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                macdSuccessRateSeries.add(new Day(day, month, year), null);
                i++;
            } else {
                Object[] obj = (Object[]) averageAllCloseList.get(i);
                Date date = (Date) obj[0];
                int year = DateUtil.getYearFromDate(date);
                int month = DateUtil.getMonthFromDate(date);
                int day = DateUtil.getDateFromDate(date);
                macdSuccessRateSeries.add(new Day(day, month, year), null);
                j++;
            }
        }
        timeSeriesCollection.addSeries(macdSuccessRateSeries);

        JFreeChart jfreechart;
        jfreechart = ChartFactory.createTimeSeriesChart("All Stock Close",
                "MACD Success Rate", "MACD Success Rate", timeSeriesCollection, true, true, true);
        jfreechart.setBackgroundPaint(Color.white);
        XYPlot xyplot = (XYPlot) jfreechart.getPlot();
        xyplot.setBackgroundPaint(Color.lightGray);
        xyplot.setDomainGridlinePaint(Color.white);
        xyplot.setRangeGridlinePaint(Color.white);
        xyplot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));
        xyplot.setDomainCrosshairVisible(true);
        xyplot.setRangeCrosshairVisible(true);
        org.jfree.chart.renderer.xy.XYItemRenderer xyitemrenderer = xyplot.getRenderer();
        if (xyitemrenderer instanceof XYLineAndShapeRenderer) {
            XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer) xyitemrenderer;
            xylineandshaperenderer.setBaseShapesVisible(true);
            xylineandshaperenderer.setBaseShapesFilled(true);
            xylineandshaperenderer.setSeriesPaint(2, Color.BLACK);
        }
        DateAxis dateaxis = (DateAxis) xyplot.getDomainAxis();
        dateaxis.setDateFormatOverride(new SimpleDateFormat("yyyy-MM-dd"));

        try {
            FileOutputStream fos = new FileOutputStream(PICTURE_PATH + "macd_success_rate/" + beginDate + "-" + endDate + PICTURE_FORMAT);
            // 将统计图标输出成JPG文件
            ChartUtilities.writeChartAsJPEG(fos, // 输出到哪个输出流
                    1, // JPEG图片的质量，0~1之间
                    jfreechart, // 统计图标对象
                    imageWidth,// 宽
                    IMAGE_HEIGHT,// 高
                    null // ChartRenderingInfo 信息
            );
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*********************************************************************************************************************
     *
     * 												计算全部数据
     *
     *********************************************************************************************************************/
    /**
     * 使用日线级别MACD金叉模型算法，向表MDL_MACD_GOLD_CROSS插入数据
     */
    public void writeModelMACDGoldCross() {
        modelMACDGoldCrossDao.writeModelMACDGoldCross();
    }

    @Override
    public String listToString(List list) {
        // TODO Auto-generated method stub
        return null;
    }
}






